package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.dto.ElderFamilyDto;
import com.zzyl.nursing.mapper.BedMapper;
import com.zzyl.nursing.mapper.ContractMapper;
import com.zzyl.nursing.mapper.ElderMapper;
import com.zzyl.nursing.util.CodeGenerator;
import com.zzyl.nursing.mapper.CheckInConfigMapper;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.CheckInMapper;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;
/**
 * 入住Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-07-26
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper,CheckIn> implements ICheckInService
{
    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private CheckInConfigMapper checkInConfigMapper;

    /**
     * 查询入住
     * 
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询入住列表
     * 
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn)
    {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn)
    {
        return save(checkIn)?1:0;
    }

    /**
     * 修改入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn)
    {
        return updateById(checkIn)?1:0;
    }

    /**
     * 批量删除入住
     * 
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids))?1:0;
    }

    /**
     * 删除入住信息
     * 
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id)
    {
        return removeById(id)?1:0;
    }

    /**
     * 申请入住
     * @param dto
     * @return 结果
     */
    @Override
    public void apply(CheckInApplyDto dto) {
        //1. 校验老人是否入住
        LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<Elder>();
        queryWrapper.eq(Elder::getIdCardNo,dto.getCheckInElderDto().getIdCardNo());
        queryWrapper.eq(Elder::getStatus,1);
        Elder elder = elderMapper.selectOne(queryWrapper);
        if(ObjectUtils.isEmpty(elder)){
            throw new BaseException("该老人已入住");
        }
        //2. 更新创维状态为已入住
        //2.1 查询床位信息
        Bed bed = bedMapper.selectBedById(dto.getCheckInConfigDto().getBedId());
        //2.2 改为已入住
        bed.setBedStatus(1);
        //2.3 再放回到数据中
        bedMapper.updateById(bed);
        //3. 新增或更新老人
        //3.1 因为上述elder对象在有老人入住是直接抛异常后面不走因此 , 当走到这里时说明 elder对象是空的, 所有直接覆盖掉上一次的
        elder = insertOrUpdateElder(dto.getCheckInElderDto() , bed);
        //4. 新增签约办理
        insertContract(elder , dto);
        //5. 新增入住信息
        CheckIn checkIn =  insertCheckIn(elder , dto);
        //6. 新增入住配置
        insertCheckInConfig(checkIn , dto);


    }



    private void insertCheckInConfig(CheckIn checkIn , CheckInApplyDto dto) {
        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(dto.getCheckInConfigDto() , checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
        checkInConfigMapper.insert(checkInConfig);
    }

    /**
     * 新增入住信息
     * @param elder
     * @param dto
     */
    private CheckIn insertCheckIn(Elder elder, CheckInApplyDto dto) {
        //创建入住对象
        CheckIn checkIn = new CheckIn();
        //添加入住信息
        checkIn.setElderName(elder.getName());
        checkIn.setElderId(elder.getId());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setBedNumber(elder.getBedNumber());
        checkIn.setStartDate(dto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(dto.getCheckInConfigDto().getEndDate());
        checkIn.setNursingLevelName(dto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setStatus(0);
        //插入老人家属信息 , 因为只用于数据展示 , 因此转换为json字符串存入checkIn的remark字段中
        //转为json字符串
        String jsonString = JSON.toJSONString(dto.getElderFamilyDtoList());
        checkIn.setRemark(jsonString);
        //json转对象
        List<ElderFamilyDto> list = JSON.parseArray(jsonString, ElderFamilyDto.class);
        System.out.println( list);
        checkInMapper.insert(checkIn);
        return checkIn;
    }

    /**
     * 新增合同信息
     * @param elder
     */
    private void insertContract(Elder elder , CheckInApplyDto dto) {
        //4.1 创建合同对象
        Contract contart = new Contract();
        //4.2 属性拷贝
        BeanUtils.copyProperties(dto.getCheckInContractDto() , contart);
        //4.3 添加创建人
        contart.setElderId((int) elder.getId());
        //4.4 调工具类生成16位编号
        contart.setContractNumber("HT" + CodeGenerator.generateContractNumber());
        contart.setElderName(elder.getName());
        //4.5 拿到合同的开始和结束时间
        LocalDateTime startDate = dto.getCheckInConfigDto().getStartDate();
        LocalDateTime endDate = dto.getCheckInConfigDto().getEndDate();
        contart.setStartDate(startDate);
        contart.setEndDate(endDate);
        //4.6 判断合同状态
        //开始时间在此刻时间之前, 生效
        Integer status =  startDate.isBefore(LocalDateTime.now()) ? 1 : 0;
        contart.setStatus(status);
        //4.7 保存合同
        contractMapper.insert(contart);

    }

    /**
     * 新增或更新老人
     * @param checkInElderDto 前端传递过来的床位信息
     * @param bed
     */
    private Elder insertOrUpdateElder(CheckInElderDto checkInElderDto, Bed bed) {
        //创建老人对象
        Elder e = new Elder();
        //因为没有数据将前端传递过来的数据复制给对象 , 因为前端没给床位ID和编号需要自己添加
        BeanUtils.copyProperties(checkInElderDto , e);
        //床位ID
        e.setBedId(bed.getId());
        //床位编号
        e.setBedNumber(bed.getBedNumber());
        e.setStatus(1);
        //查找是否是新增或者更新 , 需要注意checkInElderDto是前端传过来的数据
        LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<Elder>();
        queryWrapper.eq(Elder::getIdCardNo,checkInElderDto.getIdCardNo());
        queryWrapper.eq(Elder::getStatus,0);
        Elder elder = elderMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(elder)){
            e.setId(elder.getId());
            //;老人已存在更新
            elderMapper.updateById(e);

        }else{
            //老人不存在新增 , 在这里用MP的原因是更新时间修改时间MP均可以帮你自动生成
            elderMapper.insert(e);
        }
        return e;
    }


    /**
     * 申请入住详细
     *
     * @param id
     * @return
     */
    @Override
    public CheckInDetailVo detail(Long id) {
        CheckInDetailVo vo = new CheckInDetailVo();
        // 入住信息
        CheckIn checkIn = checkInMapper.selectCheckInById(id);
        Long elderId = checkIn.getElderId();

        // 老人的信息
        Elder elder = elderMapper.selectElderById(elderId);
        // 如果老人信息不为空，则构建入住老人信息对象
        if(elder != null){
            String age = elder.getIdCardNo();
            CheckInElderVo checkInElderVo = new CheckInElderVo();
            // 复制老人基本信息到入住老人对象
            BeanUtils.copyProperties(elder, checkInElderVo);
            // 设置年龄信息（从身份证号中提取）
            checkInElderVo.setAge(Integer.valueOf(age));
            vo.setCheckInElderVo(checkInElderVo);
        }

        // 入住配置信息
        LambdaQueryWrapper<CheckInConfig> queryWrapper = new LambdaQueryWrapper<>();
        //入职参数id
        queryWrapper.eq(CheckInConfig::getCheckInId, checkIn.getId());
        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(queryWrapper);
        //将checkInConfig信息转换为checkInConfigvo对象
        CheckInConfigVo checkInConfigVo = BeanUtil.toBean(checkInConfig, CheckInConfigVo.class);
        //添加床号
        checkInConfigVo.setBedNumber(checkIn.getBedNumber());
        //开始入住时间
        checkInConfigVo.setStartDate(checkIn.getStartDate());
        //结束入住时间
        checkInConfigVo.setEndDate(checkIn.getEndDate());
        vo.setCheckInConfigVo(checkInConfigVo);

        // 老人家属信息
        String familyInfo = checkIn.getRemark();
        //
        // 转换为json字符串存入checkIn的remark字段中
        vo.setElderFamilyVoList(JSON.parseArray(familyInfo, ElderFamilyVo.class));

        // 合同信息
        LambdaQueryWrapper<Contract> contractQueryWrapper = new LambdaQueryWrapper<>();
        //合同id
        contractQueryWrapper.eq(Contract::getElderId, elderId);
        Contract contract = contractMapper.selectOne(contractQueryWrapper);
        vo.setContract(contract);

        return vo;
    }
}
